//
//  DXMLEventObject.m
//  DerbyStatter
//
//  Created by glenn andreas on 1/29/14.
//  Copyright (c) 2014 glenn andreas. All rights reserved.
//

#import "DXMLEventObject.h"

@implementation DXMLEventObject
- (void) setEventSourceIfNeeded: (DXMLEventSource) source
{
    if (self.source == DXMLEventSourceUnknown) {
        self.source = source;
    }
}
- (NSInteger) numberOfChildrenOfClass: (Class) cls;
{
    __block NSInteger total = 0;
    [self enumerateChildren:^(DXMLEventObject *child, BOOL *stop) {
        total++;
    } ofClass:cls];
    return total;
}
- (id) childOfClass: (Class) cls atIndex: (NSInteger) index
{
    __block DXMLEventObject *retval = nil;
    __block NSInteger total = 0;
    [self enumerateChildren:^(DXMLEventObject *child, BOOL *stop) {
        if (total == index) {
            retval = child;
            *stop = YES;
        }
        total++;
    } ofClass:cls];
    return retval;
}
- (id) childOfClass: (Class) cls atIndex: (NSInteger) index source: (DXMLEventSource) source;
{
    __block DXMLEventObject *retval = nil;
    __block NSInteger total = 0;
    [self enumerateChildren:^(DXMLEventObject *child, BOOL *stop) {
        if (total == index) {
            retval = child;
            *stop = YES;
        }
        total++;
    } ofClass:cls];
    if (!retval) {
        while (total != index+1) {
            retval = [[cls alloc] init];
            [retval setSource:source];
            retval.parent = self;
            if ([retval respondsToSelector:@selector(number)]) {
                [retval setValue:@(total+1) forKey:@"number"]; // number is one based
            }
            [self addChild:retval];
            total++;
        }
    }
    return retval;
}
- (void) enumerateChildren: (void (^)(DXMLEventObject *child, BOOL *stop)) block ofClass: (Class) cls;
{
    for (DXMLEventObject *child in self.children) {
        if ([child isKindOfClass:cls]) {
            BOOL stop = NO;
            block(child,&stop);
            if (stop)
                break;
        }
    }
}
- (void) enumerateChildren: (void (^)(DXMLEventObject *child, BOOL *stop)) block;
{
    for (DXMLEventObject *child in self.children) {
            BOOL stop = NO;
            block(child,&stop);
            if (stop)
                break;
    }
}
- (id) createChild: (Class) cls
{
    id retval = [[cls alloc] init];
    [self addChild:retval];
    [retval setParent: self];
    return retval;
}
- (id) createChild: (Class) cls source:(DXMLEventSource)source
{
    id retval = [[cls alloc] init];
    [self addChild:retval];
    [retval setParent: self];
    [retval setSource:source];
    return retval;
}
//- (void) addChild: (DXMLEventObject *) child
//{
//    if (![self.children containsObject:child]) {
//        child.parent = self;
//        [super addChild:child];
//    }
//}
//- (void) removeChild: (DXMLEventObject *) child
//{
//    [super removeChild:child];
//}
@end
